import os
from math import log
from dataFormat import TextNode
import cnl2mc_console
import instanceFactory

class Coder:
    
    def __init__(self):
        self.path = ".." ##<TODO> config this path
        self.console = cnl2mc_console.Console()
        self.console.config("../config/config_ecl.xml")
        
    def getWeightDict(self, weightModelFile):
        tokenWeightDict = {}
        try:
            weightModel = open(weightModelFile, "rU")
            for line in weightModel:
                (kStr, vStr) = line.split(":")
                tokenWeightDict[kStr] = float(vStr)            
        finally:
            weightModel.close()
        return tokenWeightDict
    
    def wrapText(self, text):
        preprocessor = instanceFactory.InstanceFactory.getInstance().getPreprocessor()
        dataNode = TextNode(reqID= -1, textStr=text, classList = None, preproc = preprocessor)
        dataNodeDict = {-1:dataNode}
        return dataNodeDict
        
    
    def preprocess(self, dataNodeDict):
        self.console.preprocess(dataNodeDict)
        return 
    
    def tokenizeText(self, text):
        dataNodeDict = self.wrapText(text)
        self.preprocess(dataNodeDict)
        dataNode = dataNodeDict[-1]
        return dataNode.wordsFreqDist
        
        
    def getTextVectorList(self, text, weightModelFilename, orderedTermList):
        termWeightDict = self.getWeightDict(weightModelFilename)
        tokenFreqDist = self.tokenizeText(text)
        termList = tokenFreqDist.keys()
        orderedTermListLength = len(orderedTermList)
        vectorList = []        
        for i in xrange(orderedTermListLength):
            term = orderedTermList[i]
            try:
                if orderedTermList[i] in termList:
                    weight = self.calculateEntropyWeight(tokenFreqDist, tokenFreqDist[term], termWeightDict[term])
                    vectorList.append("%s:%s"%(str(i+1), weight))                  
            except Exception:
                pass
        return vectorList
    
    def calculateEntropyWeight(self, localFrequency, baseValue):
        entropyWeight = (log(localFrequency + 1.0))*(1.0 + baseValue)
        return entropyWeight        
        
    def hasTheCode(self, vectorList, code):
        classified = "-1"
        """
        
        """
        return classified == "+1"     
    
    def getWmfByCode(self, code):
        modelFileName = "%s_TermWeightModel.mod"%code
        return os.path.join(self.path, modelFileName)
    
    def getOtlByCode(self, code):
        orderedTermListFile = "%s_OrderedTermListFile.lst"%code
        codeListFilename = os.path.join(self.path, orderedTermListFile)        
        try:
            listFile = open(codeListFilename, "rU")
            list = listFile.read().split()
        finally:
            listFile.close()
        return list
    
    def getResultCodes(self, text, codeList):
        resultCodes = []
        for c in codeList:
            weightModelFilename = self.getWmfByCode(c)
            orderedTermList = self.getOtlByCode(c) 
            vectorList = self.getTextVectorList(text, weightModelFilename, orderedTermList)
            if self.hasTheCode(vectorList, c):
                resultCodes.append(c)
        return resultCodes
        
    
if __name__ == "__main__":
    coder = Coder()
    
    modelFilename = os.path.join(coder.path, "M9000_TermWeightModel.mod")
    modelExample = ["001:0.336", "889:-0.02", "k-wwr:0.00"]
    open(modelFilename, "w+").write("\n".join(modelExample))
    
    lstFilename = os.path.join(coder.path, "M9000_OrderedTermListFile.lst")    
    lstExample = ["heart_s-1", "k-wwr", "00101", "889"]
    open(lstFilename, "w+").write("\n".join(lstExample))
    
    textExample = "001 heart_s-1 889 00101 k-wwr"
    
    termWeightDict = coder.getWeightDict(modelFilename)
    print termWeightDict
    print coder.getTextVectorList(textExample, modelFilename, lstExample)
    print coder.getResultCodes(textExample, ['M9000', ])
     
        
    